﻿using Novel.Sync.Entity;
using Novel.Sync.Service;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using XjjXmm.FrameWork.ToolKit;
using XjjXmm.Spider;

namespace Novel.Sync.SyncUtil
{
    internal class NovelSync
    {
        internal static string ExportFolder {get;set;}

        private SqlSugarScope _sqlSugarClient;
        public NovelSync(SqlSugarScope sqlSugarClient)
        {
            _sqlSugarClient = sqlSugarClient;
        }

        public void Run()
        {
            SyncNovel();
        }

        private async Task SyncNovel()
        {
            // var name = _sqlSugarClient.GetConnection("1").SplitHelper<BookChapter>().GetTableName("1501198437834690560");
            // var res = _sqlSugarClient.GetConnection("1").Queryable<BookChapter>().SplitTable(tas => tas.InTableNames(name)).ToList();

            var begin = DateTime.Now;
            var novels = await _sqlSugarClient.Queryable<NovelEntity>().ToListAsync();
            foreach (var t in novels)
            {
                SyncNovel(t);
            }


            Serilog.Log.Information($"SyncNovel完成， 用时：{DateTime.Now.Subtract(begin).TotalMilliseconds}");


        }

        /// <summary>
        /// 事务部不起作用
        /// </summary>
        /// <param name="novelEntity"></param>
        private void SyncNovel(NovelEntity novelEntity)
        {
            try
            {
                //var bookdb = _sqlSugarClient.GetConnection(1);
                //var noveldb = _sqlSugarClient.GetConnection(0);
                Serilog.Log.Information($"{novelEntity.Title}准备开始");

                var start = DateTime.Now;

                _sqlSugarClient.BeginTran();
                _sqlSugarClient.ChangeDatabase("1");
                #region 更新novel
                var book = new BookEntity
                {
                    //Id = 
                    Title = novelEntity.Title,
                    Author = novelEntity.Author,

                    Category = novelEntity.Category,
                    Intro = novelEntity.Intro,

                    IsInstalment = novelEntity.IsInstalment,

                    UpdateTime = novelEntity.UpdateTime,
                    LastChapter = novelEntity.LastChapter ,

                };

                var exitBook = _sqlSugarClient.Queryable<BookEntity>().Where(t => t.Title == book.Title && t.Author == book.Author).First();
                long bookId = 0;
                if (exitBook == null)
                {
                    bookId = _sqlSugarClient.Insertable<BookEntity>(book).ExecuteReturnSnowflakeId();
                }
                else
                {
                    bookId = exitBook.Id;
                    book.Id = exitBook.Id;
                    _sqlSugarClient.Updateable<BookEntity>(book).ExecuteCommand();
                }



                #endregion

                #region 生成文章列表
                _sqlSugarClient.ChangeDatabase("0");
                var chapters = _sqlSugarClient.Queryable<NovelChapter>().Where(x => x.NovelId == novelEntity.Id).ToList();

                _sqlSugarClient.ChangeDatabase("1");
                var tableName = _sqlSugarClient.SplitHelper<BookChapter>().GetTableName(bookId);
                _sqlSugarClient.Deleteable<BookChapter>().Where(x => x.NovelId == bookId).SplitTable(tas => tas.InTableNames(tableName)).ExecuteCommand();

                var folder = Path.Combine(ExportFolder, WordSplitService.GetFirstCode(bookId.ToString()));
                if (!Directory.Exists(folder))
                {
                    Directory.CreateDirectory(folder);
                }

                var file = Path.Combine(folder, $"{bookId}.xml");
                if (File.Exists(file))
                {
                    File.Delete(file);
                }
                WriteHeader(file, novelEntity.Title, novelEntity.Author);
                foreach (var chapter in chapters)
                {
                    var chapterId = SyncChapter(bookId, chapter);

                    WriteBody(file, chapter, chapterId);
                }

                WriteFooter(file);
                //var bookChapters = chapters.Select(t => ).ToList();

                CompressKit.Compress7z(file).ContinueWith(t =>
                {
                    File.Delete(file);

                    _sqlSugarClient.ChangeDatabase("0");
                    _sqlSugarClient.Updateable<NovelPoolEntity>()
                        .SetColumns(t => t.IsGenerator == true)
                        .Where(t => t.Title == book.Title && t.Author == book.Author)
                        .ExecuteCommand();

                    //Serilog.Log.Information($"{book.Title}生成完成");

                    Serilog.Log.Information($"{novelEntity.Title}完成， 用时：{DateTime.Now.Subtract(start).TotalMilliseconds}");

                });


                #endregion

                #region 生成内容

                #endregion

               


                _sqlSugarClient.CommitTran();
            }
            catch (Exception ex)
            {
                _sqlSugarClient.RollbackTran();

                Serilog.Log.Error(ex, $"{novelEntity.Title}失败");
            }
        }

        private long SyncChapter(long bookId, NovelChapter chapter)
        {
            var bookChapter = new BookChapter
            {
                Title = chapter.Title,
                NovelId = bookId
            };

            return _sqlSugarClient.Insertable(bookChapter).SplitTable().ExecuteReturnSnowflakeId();//插入返回雪花ID集合


        }

        private void WriteHeader(string file, string title, string author)
        {
            File.AppendAllText(file, "<?xml version=\"1.0\" encoding=\"utf-8\" ?>");
            File.AppendAllText(file, System.Environment.NewLine);
            File.AppendAllText(file, "<book>");
            File.AppendAllText(file, System.Environment.NewLine);
            File.AppendAllText(file, $"<title>{title}</title>");
            File.AppendAllText(file, System.Environment.NewLine);
            File.AppendAllText(file, $"<author>{author}</author>");
            File.AppendAllText(file, System.Environment.NewLine);
            File.AppendAllText(file, "<chapters>");
            File.AppendAllText(file, System.Environment.NewLine);
        }

        private void WriteBody(string file, NovelChapter chapter, long chapterId)
        {
            File.AppendAllText(file, $"<chapter id=\"{chapterId}\">");
            File.AppendAllText(file, System.Environment.NewLine);
            File.AppendAllText(file, $"<title>{chapter.Title}</title>");

            File.AppendAllText(file, System.Environment.NewLine);
            File.AppendAllText(file, $"<contents>");
            //File.AppendAllText(file, System.Environment.NewLine);
           // File.AppendAllText(file, "<![CDATA[");
            foreach(var content in ProcessContent(chapter.Content))
            {
                File.AppendAllText(file, System.Environment.NewLine);
                File.AppendAllText(file, $"<content>{content}</content>");
            }
            File.AppendAllText(file, System.Environment.NewLine);

            // File.AppendAllText(file, System.Environment.NewLine);
            // File.AppendAllText(file, $"{ProcessContent(chapter.Content)}");
            // File.AppendAllText(file, System.Environment.NewLine);
            // File.AppendAllText(file, "]]>");
            //File.AppendAllText(file, System.Environment.NewLine);
            File.AppendAllText(file, $"</content>s");

            File.AppendAllText(file, System.Environment.NewLine);
            File.AppendAllText(file, "</chapter>");
            File.AppendAllText(file, System.Environment.NewLine);
        }

        private void WriteFooter(string file)
        {
            File.AppendAllText(file, "</chapters>");
            File.AppendAllText(file, System.Environment.NewLine);
            File.AppendAllText(file, "</book>");
        }

        private async Task<string> Write(long novelId, List<NovelChapter> chapters)
        {

            var file = $"1/1.xml";

            if (File.Exists(file))
            {
                File.Delete(file);
            }


            //XmlReader reader = XmlReader.Create()
            foreach (var chapter in chapters)
            {

                //await File.AppendAllTextAsync($"1/{chapter.Title}.txt", chapter.Content);
                //await File.AppendAllTextAsync("1/1.txt", chapter.Title);
                //await File.AppendAllTextAsync("1/1.txt", System.Environment.NewLine);
                //await File.AppendAllTextAsync("1/1.txt", chapter.Content);
            }


            await CompressKit.Compress7z(file);
            return file;
        }

        private IEnumerable<string> ProcessContent(string content)
        {
            return Regex.Replace(content, "<br>", "\n").Replace("&nbsp;", "").Split('\n')
             .Where(t => t != "");
           
            //return content.Replace("&nbsp;", "");
        }
    }
}
